package com.yonyou.wdt.job;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yonyou.wdt.entity.OpenApiURLEnum;
import com.yonyou.wdt.entity.QueryDto;
import com.yonyou.wdt.job.config.BaseConfig;
import com.yonyou.wdt.service.YonsuiteService;
import com.yonyou.wdt.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName YsAllocationOutToWdtJob
 * @Description YS 销售发货同步旺店通售后单
 * @Author HuangWb
 * @Date 2023/5/12 10:24
 * @Version 1.0
 */
@Component
public class YsSalereturnToWdtJobNew extends BaseConfig {

	private final WdtConfigProperties configProperties;

	private final Logger logger = LoggerFactory.getLogger(YsSalereturnToWdtJobNew.class);

	@Resource
	private YonsuiteService yonsuiteService;

	private static final String JOB_CLASS="maoEr005";

	@Autowired
	public YsSalereturnToWdtJobNew(WdtConfigProperties configProperties) {
		this.configProperties = configProperties;
	}
	
	@XxlJob("YsSalereturnToWdtJobNew")
	public ReturnT<String> ysSalereturnToWdtJob(String params) throws Exception {
		String param = XxlJobHelper.getJobParam();
		Map<String, Object> map = new HashMap<>();
		if (param != null && !"".equals(param)) {
			List<String> timeRange = Arrays.asList(param.split("\\|"));
			if (timeRange.size() == 2) {
				map.put("Start", timeRange.get(0));
				map.put("End", timeRange.get(1));
			} else {
				map.put("code",timeRange.get(0));
			}
		} else {
			map.put("Start", DateUtils.getStartDateBy10m());
			map.put("End", DateUtils.getEndDateBy10m());
		}
		// 处理相关业务
		QueryDto dto = new QueryDto();
		dto.setTenantId(getYsTenantId());
		dto.setAppKey(getYsAppKey());
		dto.setAppSecret(getYsAppSecret());
		// 获取YS系统租户动态域名信息
		ReturnT<String> isReturn2 = getYsDynamicDomainName(JOB_CLASS,dto);
		// 域名获取失败
		if (isReturn2 != null) return isReturn2;
		try {
			// 根据客户
			Object o = RedisUtils.get(dto.getTenantId() + ":2BCust");
			if (o==null){
				InsertLogger(JOB_CLASS,null, "0", "YS销售退货查询失败，未找到2B客户");
			}
			List<JSONObject> list = JSONUtil.toList(JSONUtil.toJsonStr(o), JSONObject.class);

			ArrayList<JSONObject> ysSaleReturnList = getYsSaleReturnList(map, dto,list);
			if (ysSaleReturnList.isEmpty()) {
				logger.info("当前时间段{}-{}，YS销售退货为空", map.get("Start"), map.get("End"));
				return ReturnT.SUCCESS;
			}


			Map<String, List<JSONObject>> groupByIdMap = groupById(ysSaleReturnList);
			int index = 1;
			for (Map.Entry<String, List<JSONObject>> idKey : groupByIdMap.entrySet()) {
				//自定义档案列表查询
				HashMap<String, String> custData = YsQueryUtil.getFhdpDef(dto,yonsuiteService);
				List<JSONObject> value = idKey.getValue();
				//销售订单列表查询
				List<JSONObject> ysSaleOrderList=getYsSaleOrderList(value.get(0),dto);
				String ysCode = value.get(0).getStr("code");
				JSONObject response=sendWdt(ysSaleOrderList,value,list,custData);
				if (response != null) {
					if (null != response && response.getInt("code") == 0) {
						logger.info("YS销售退货：{} 同步旺店通原始退款单成功", ysCode);
						InsertLogger(JOB_CLASS,ysCode, "1", "YS销售退货：{"+ysCode+"}同步旺店通原始退款单成功。");
					} else {
						if (null != response) {
							logger.error("YS销售退货：{} 同步旺店通原始退款单失败,原因：{}", ysCode, response.getStr("message"));
							InsertLogger(JOB_CLASS,ysCode, "0", "YS销售退货：{"+ysCode+"}同步旺店通原始退款单失败："+response.getStr("message"));

						} else {
							logger.error("YS销售退货：{} 同步旺店通原始退款单失败，旺店通接口未返回数据", ysCode);
							InsertLogger(JOB_CLASS,ysCode, "0", "YS销售退货：{"+ysCode+"}同步旺店通原始退款单失败：旺店通接口未返回数据。");
						}
					}
				} else {
					logger.error("YS销售退货单：{}，同步旺店售后单失败",ysCode);
					InsertLogger(JOB_CLASS,ysCode, "0", "YS销售退货：{"+ysCode+"}同步旺店通原始退款单失败：联系开发解决。");
				}
				// 旺店通接口频率问题处理
				this.APICurrentLimiting("sales_refund_push.php",60);
			}
		} catch (Exception e) {
			logger.error("Error occurred", e);
			logger.error("YS销售退货同步旺店通售后单失败：{}", e.getMessage());
			return ReturnT.FAIL;
		}
		
		logger.info("  --  YS销售退货同步旺店通售后单任务执行完成  --  ");
		return ReturnT.SUCCESS;
	}

	public static void main(String[] args) {
		String s="1.2346";
		System.out.println(BigDecimal.valueOf(Double.parseDouble(s)));
	}
	private List getYsSaleOrderList(JSONObject value, QueryDto dto) throws Exception {
		ArrayList<JSONObject> deliveryResponseList = new ArrayList<>();
		HashMap<String, Object> saleOutQueryMap = new HashMap<>();
		saleOutQueryMap.put("pageSize", 100);
		saleOutQueryMap.put("pageIndex", 1);
		saleOutQueryMap.put("isSum", false);
		HashMap<String, Object> simpleVosMap = new HashMap<>();
		simpleVosMap.put("field", "code");
		simpleVosMap.put("op", "eq");
		simpleVosMap.put("value1", value.getStr("upcode"));
		ArrayList<Map<String, Object>> simpleVosList = new ArrayList<>();
		simpleVosList.add(simpleVosMap);
		saleOutQueryMap.put("simpleVOs", simpleVosList);
		JSONObject saleOutResponse = yonsuiteService.saleOutList(saleOutQueryMap, dto);
		if ("200".equals(saleOutResponse.getStr("code"))) {
			if (null != saleOutResponse.getJSONObject("data") && null != saleOutResponse.getJSONObject("data").getJSONArray("recordList")) {
				JSONArray saleOutJsonArray = saleOutResponse.getJSONObject("data").getJSONArray("recordList");
				if (saleOutJsonArray.isEmpty()){
					InsertLogger(JOB_CLASS,value.getStr("upcode"), "0", "YS销售退货查询出库单：{"+value.getStr("upcode")+"}失败：联系开发解决。");

				}
				JSONObject saleOutJSON = JSONUtil.parseObj(saleOutJsonArray.get(0));
				//发货单号
				String deliveryCode = saleOutJSON.getStr("upcode");
				HashMap<String, Object> saleDeliveryQueryMap = new HashMap<>();
				saleDeliveryQueryMap.put("pageSize", 100);
				saleDeliveryQueryMap.put("pageIndex", 1);
				saleDeliveryQueryMap.put("isSum", false);
				HashMap<String, Object> codeSimpleVosMap = new HashMap<>();
				codeSimpleVosMap.put("field", "code");
				codeSimpleVosMap.put("op", "eq");
				codeSimpleVosMap.put("value1", deliveryCode);
				ArrayList<Map<String, Object>> deliverysimpleVosList = new ArrayList<>();
				deliverysimpleVosList.add(codeSimpleVosMap);
				saleDeliveryQueryMap.put("simpleVOs", deliverysimpleVosList);
				int pageIndex = 1;

				int errorIndex = 0;
				while (true) {
					saleOutQueryMap.put("pageIndex", pageIndex);
					JSONObject deliveryResponse = yonsuiteService.saleDeliveryQuery(saleDeliveryQueryMap, dto);
					// 接口执行频率问题处理
					this.APICurrentLimiting(OpenApiURLEnum.SALE_STOCK_RETURN_QUERY, 59);

					if ("200".equals(deliveryResponse.getStr("code"))) {
						if (null != deliveryResponse.getJSONObject("data") && null != deliveryResponse.getJSONObject("data").getJSONArray("recordList")) {
							JSONArray purJsonArray = deliveryResponse.getJSONObject("data").getJSONArray("recordList");
							for (Object pur : purJsonArray) {
								JSONObject purJson = (JSONObject) pur;
								deliveryResponseList.add(purJson);
							}
						}
						if (deliveryResponse.getJSONObject("data").getInt("pageCount") <= pageIndex) {
							break;
						}
						// 接口执行频率问题处理
						this.APICurrentLimiting(OpenApiURLEnum.SALE_DELIVERY_QUERY, 19);

						pageIndex++;
					} else {
						if (errorIndex < 10) {
							errorIndex++;
							logger.error("查询YS销售退货单第：{}，页失败：{},延迟一秒查询", pageIndex, deliveryResponse.getOrDefault("message", "接口未返回数据"));
							Thread.sleep(1000);
						} else {
							// 多次失败， 退出定时任务排查原因
							logger.error("YS销售退货单同步旺店通售后单定时任务多次执行失败，此次任务作废");
							return new ArrayList<>();
						}
					}
				}
			}
		} else {
			InsertLogger(JOB_CLASS,value.getStr("upcode"), "0", "YS销售退货：{"+value.getStr("upcode")+"}同步旺店通原始退款单失败：联系开发解决。");

		}
		return deliveryResponseList;
	}


	/**
	 * @return
	 * @Author Huangwb
	 * @Description 查询YS销售退货单列表
	 * @Date 10:36 2023/5/12
	 * @Param
	 **/
	private ArrayList<JSONObject> getYsSaleReturnList(Map<String, Object> map, QueryDto dto,List<JSONObject> list) throws Exception {
		HashMap<String, Object> queryMap = new HashMap<>();
		queryMap.put("pageSize", 100);
		queryMap.put("isSum", false);
		// queryMap.put("open_vouchdate_begin", map.get("Start"));  // 开始时间
		// queryMap.put("open_vouchdate_end", map.get("End"));  // 结束时间
		queryMap.put("saleReturnStatus", "ENDSALERETURN");//单据状态, SUBMITSALERETURN:开立、CONFIRMSALERETURNORDER:已确认、SALERETURNING:退货中、ENDSALERETURN:已审核、OPPOSESALERETURN:已驳回、
		queryMap.put("saleReturnSourceType", "DELIVERYEND");//退货类型, NONE:无来源、DELIVERYEND:销售出库单、ORDER:销售订单
		ArrayList<Map<String, Object>> simpleVosList = new ArrayList<>();
		if (map.get("code")!=null){
			queryMap.put("code", map.get("code").toString());
		}else {
			HashMap<String, Object> simpleVosMap = new HashMap<>();
			simpleVosMap.put("field", "auditTime");
			simpleVosMap.put("op", "between");
			simpleVosMap.put("value1", map.get("Start"));
			simpleVosMap.put("value2", map.get("End"));
			simpleVosList.add(simpleVosMap);
		}

		List<String> collect = list.stream().map(obj ->obj.getStr("id")).collect(Collectors.toList());
		HashMap<String, Object> bustypeMap = new HashMap<>();
		bustypeMap.put("field", "agentId");
		bustypeMap.put("op", "in");
		bustypeMap.put("value1", collect);
		simpleVosList.add(bustypeMap);
		queryMap.put("simpleVOs", simpleVosList);
		int pageIndex = 1;
		ArrayList<JSONObject> purList = new ArrayList<>();
		int errorIndex = 0;
		while (true) {
			queryMap.put("pageIndex", pageIndex);
			JSONObject purJsonResponse = yonsuiteService.saleReturnList(queryMap, dto);
			if ("200".equals(purJsonResponse.getStr("code"))) {
				if (null != purJsonResponse.getJSONObject("data") && null != purJsonResponse.getJSONObject("data").getJSONArray("recordList")) {
					JSONArray purJsonArray = purJsonResponse.getJSONObject("data").getJSONArray("recordList");
					for (Object pur : purJsonArray) {
						JSONObject purJson = (JSONObject) pur;
						purList.add(purJson);
					}
				}
				if (purJsonResponse.getJSONObject("data").getInt("pageCount") <= pageIndex) {
					break;
				}
				// 接口执行频率问题处理
				this.APICurrentLimiting(OpenApiURLEnum.SALE_STOCK_RETURN_QUERY,59);
				pageIndex++;
			} else {
				if (errorIndex < 10) {
					errorIndex++;
					logger.error("查询YS销售退货单第：{}，页失败：{},延迟一秒查询", pageIndex, purJsonResponse.getOrDefault("message", "接口未返回数据"));
					Thread.sleep(1000);
				} else {
					// 多次失败， 退出定时任务排查原因
					logger.error("YS销售退货单同步旺店通售后单定时任务多次执行失败，此次任务作废");
					return new ArrayList<>();
				}
			}
		}
		logger.info("当前时间段{}至{}YS销售退货单有：{}条", map.get("Start"), map.get("End"), purList.size());
		return purList;
	}
	
	/**
	 * @return
	 * @Author Huangwb
	 * @Description 根据单据编号分组
	 * @Date 10:38 2023/5/12
	 * @Param
	 **/
	private Map<String, List<JSONObject>> groupById(ArrayList<JSONObject> ysPdcyList) {
		return ysPdcyList.stream().collect(Collectors.groupingBy(json -> json.getStr("id")));
	}
	
	/**
	 * @return
	 * @Author Huangwb
	 * @Description 组装旺店通请求数据，并调用旺店通接口保存数据、
	 * @Date 10:51 2023/5/12
	 * @Param
	 **/
	private JSONObject sendWdt(List<JSONObject> ysSaleOrderList,List<JSONObject> rkValue,List<JSONObject> list,HashMap<String, String> custData){
		
		//JSONObject ckJsonObject = rkValue.get(0);  // 分组第一条数据（用主表的几个字段）
		JSONObject entries = JSONUtil.parseObj(rkValue.get(0));
		String ysCode = entries.getStr("code");  // 单据号
		String shopNo= custData.get(entries.getJSONObject("salereturnDefineCharacter").getOrDefault("maoer03", "").toString());

		HashMap<String, Object> stringObjectHashMap = new HashMap<>();
		stringObjectHashMap.put("shop_no",shopNo);
		stringObjectHashMap.put("platform_id",127);
		stringObjectHashMap.put("shop_no",shopNo);
		stringObjectHashMap.put("tid",ysSaleOrderList.get(0).getStr("code"));
		stringObjectHashMap.put("refund_no",ysCode);
		stringObjectHashMap.put("type",3);
		stringObjectHashMap.put("status","goods_receiving");
		stringObjectHashMap.put("buyer_nick","ys");
		stringObjectHashMap.put("refund_time",entries.getStr("vouchdate"));
		stringObjectHashMap.put("desc","YS销售退货");
		ArrayList<Map> orderListMaps = new ArrayList<>();
		for (Object outJsonObj : rkValue) {
			JSONObject outJson = (JSONObject) outJsonObj;
			HashMap<String, Object> detailMap = new HashMap<>();
			JSONObject jsonObject1 = ysSaleOrderList.stream().filter(o -> o.getStr("lineno").equals(outJson.getStr("firstlineno"))).findAny().get();
			String sourceautoid = jsonObject1.getStr("orderDetailId");
			detailMap.put("oid",jsonObject1.getStr("orderId")+"_"+sourceautoid);
			//detailMap.put("oid",jsonObject1.getStr("id")+"_"+jsonObject1.getStr("deliveryDetailId"));
			detailMap.put("num",outJson.getBigDecimal("qty"));
			orderListMaps.add(detailMap);
		}
		stringObjectHashMap.put("order_list",orderListMaps);
		ArrayList<Map> refundList = new ArrayList<>();
		refundList.add(stringObjectHashMap);
		String jsonStr = JSONUtil.toJsonStr(refundList);
		HashMap<String, Object> reqMap = new HashMap<>();
		reqMap.put("api_refund_list",jsonStr);
		WdtClient client = new WdtClient(configProperties.getSid(), configProperties.getKey(), configProperties.getSecret(), configProperties.getUrl());
		String res = null;
		try {
			res = client.execute("sales_refund_push.php", reqMap);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return JSONUtil.parseObj(res);
	}
}
